package ru.niir.goodfil.ui;

import ru.niir.goodfil.db.Good;
import ru.niir.goodfil.db.GoodType;
import ru.niir.goodfil.db.Order;
import ru.niir.goodfil.db.StorageEnterance;
import ru.niir.goodfil.db.dic.OperationState;
import ru.niir.goodfil.exceptions.ValidationException;
import ru.niir.goodfil.ui.utils.excel.StorageEnteranceExport;
import ru.niir.goodfil.utils.SumFormat;
import ru.niir.goodfil.utils.filters.GoodsFilter;
import ru.niir.goodfil.utils.filters.StorageEnteranceFilter;

import javax.faces.model.SelectItem;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.logging.Filter;

public class StorageEnteranceBean extends PageBean {

    private String goodCode;

    private String comment;

    private int goodCount;

    private int operation;

    private int overflowCount;

    private String overflowSum;

    private int shortageCount;

    private String shortageSum;

    private GoodsFilter filter = new GoodsFilter();

    private long groupId = 12;

    private List<Good> goods;

    public StorageEnteranceBean() {
        init();
    }

    public void init(){
        applyFilter();
    }

    public void saveStorageEnterance(){

        if(hasFacesErrors()){
            return;
        }
        Good good = gf().getGoodByCode(getGoodCode().toUpperCase().replaceAll(" ",""));

        if(good == null){
            facesError("Товар с таким кодом не найден");
            return;
        }
        StorageEnterance storageEnterance = new StorageEnterance();
        storageEnterance.setGoodId(good.getId());
        storageEnterance.setGoodCount(getGoodCount());
        storageEnterance.setDate(new Date());
        storageEnterance.setComment(getComment());
        storageEnterance.setUserId(getSecurityBean().getUserId());
        storageEnterance.setOperationType(getOperation());
        storageEnterance.setGoodTypeId(good.getGoodTypeId());

        try{
            gf().saveStorageEnterance(storageEnterance);
        }catch (Exception e){
            facesError("Произошла непредвиденная ошибка. Попробуйте позже или свяжитесь с администратором.");
            return;
        }
        if(getOperation() == OperationState.ADD){
            good.setStorageCount(good.getStorageCount() + getGoodCount());
        }
        else if(getOperation() == OperationState.DEDUCT){
            int result = good.getStorageCount() - getGoodCount();
            if (result < 0){
                facesError("Количество товара не может быть отрицательным");
                return;
            }
            good.setStorageCount(result);
        }
        try {
            gf().updateGood(good);
        } catch (ValidationException e) {
            e.printStackTrace();
        }
    }

    public void reloadData(){
        setComment("");
        setGoodCount(0);
        applyFilter();
    }

    /**
     * @return
     */
    public List<SelectItem> getGoodTypesAsSelectItems() {
        List<SelectItem> result = new ArrayList<SelectItem>();
        List<GoodType> gts = gf().getGoodTypes();
        result.add(new SelectItem(-1, "Не установлена"));
        for (GoodType gt : gts) result.add(new SelectItem(gt.getId(), gt.getName()));
        return result;
    }

    public int getGoodCount() {
        return goodCount;
    }

    public void setGoodCount(int goodCount) {
        this.goodCount = goodCount;
    }

    public String getGoodCode() {
        return goodCode;
    }

    public void setGoodCode(String goodCode) {
        this.goodCode = goodCode;
    }

    private List<Good> getGoodsList(GoodsFilter filter) {
        List<Good> goods = gf().getGoods(filter);
        return goods;
    }

    public void setGoods(List<Good> goods) {
        this.goods = goods;
    }

    public List<Good> getGoods() {
        return goods;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public int getOperation() {
        return operation;
    }

    public void setOperation(int operation) {
        this.operation = operation;
    }

    public GoodsFilter getFilter() {
        return filter;
    }

    public void setFilter(GoodsFilter filter) {
        this.filter = filter;
    }

    public String getOperationAsString(){
        return OperationState.asString(getOperation());
    }

    public long getGroupId() {
        return groupId;
    }

    public int getOverflowCount() {
        return overflowCount;
    }

    public void setOverflowCount(int overflowCount) {
        this.overflowCount = overflowCount;
    }

    public String getOverflowSum() {
        return overflowSum;
    }

    public void setOverflowSum(String overflowSum) {
        this.overflowSum = overflowSum;
    }

    public int getShortageCount() {
        return shortageCount;
    }

    public void setShortageCount(int shortageCount) {
        this.shortageCount = shortageCount;
    }

    public String getShortageSum() {
        return shortageSum;
    }

    public void setShortageSum(String shortageSum) {
        this.shortageSum = shortageSum;
    }

    private int getOverflowCount(List<Good> goods){
        int ovewflow = 0;
        for(Good good : goods){
            if(good.getStorageCount() > good.getCount()){
                ovewflow += good.getGoodCountDifference();
            }
        }
        return ovewflow;
    }

    private int getShortageCount(List<Good> goods){
        int shortage = 0;
        for(Good good : goods){
            if(good.getStorageCount() < good.getCount()){
                shortage += good.getGoodCountDifference();
            }
        }
        return shortage;
    }

    private String getOverflowSum(List<Good> goods){
        double overflowSum = 0;
        for(Good good : goods){
            if(good.getStorageCount() > good.getCount()){
                overflowSum += good.getGoodCountDifference() * gf().getSimplePriceListByIdGoodAndGroupId(good.getId(), groupId).getPrice();
            }
        }
        return SumFormat.formatSum("###,###,##0.00", overflowSum);
    }

    private String getShortageSum(List<Good> goods){
        double shortageSum = 0;
        for(Good good : goods){
            if(good.getStorageCount() < good.getCount()){
                shortageSum += good.getGoodCountDifference() * gf().getSimplePriceListByIdGoodAndGroupId(good.getId(), groupId).getPrice();
            }
        }
        return SumFormat.formatSum("###,###,##0.00", shortageSum);
    }

    private void setDataForTotalRow(List<Good> goods){
        setOverflowCount(getOverflowCount(goods));
        setOverflowSum(getOverflowSum(goods));
        setShortageCount(getShortageCount(goods));
        setShortageSum(getShortageSum(goods));
    }

    public void applyFilter(){
        getFilter().setDeleted(0);
        getFilter().setIgnoreSpacesInCode(true);
        setGoods(getGoodsList(getFilter()));
        setDataForTotalRow(getGoods());
    }

    public void exportToExcel(){
        List<Good> goods = getGoods();
        if(goods == null){
            facesError("Нет элементов для выгрузки");
            return;
        }
        try {
            StorageEnteranceExport.storageEnteranceListToExcel(goods);
        } catch (IOException e) {
            e.printStackTrace();
            facesError("Произошла ошибка. Попробуйте позднее или свяжитесь с администратором");
        }
    }

}
